package com.zhangzhan.gulimallproduct.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhangzhan.gulimallcommcon.util.CopyBean;
import com.zhangzhan.gulimallcommcon.util.PageUtils;
import com.zhangzhan.gulimallcommcon.util.Query;
import com.zhangzhan.gulimallcommcon.util.R;
import com.zhangzhan.gulimallproduct.dao.CategoryDao;
import com.zhangzhan.gulimallproduct.entity.CategoryEntity;
import com.zhangzhan.gulimallproduct.service.CategoryBrandRelationService;
import com.zhangzhan.gulimallproduct.service.CategoryService;
import com.zhangzhan.gulimallproduct.vos.CategoryVo;
import com.zhangzhan.gulimallproduct.vos.Catelog2Vo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private CategoryBrandRelationService categoryBrandRelationService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * @return com.zhangzhan.gulimallcommcon.util.R
     * @description 查询所有商品分类展示树形结构
     * @author zhangyiheng
     * @date 2024/6/13 2:35
     */
    @Override
    public R listTree() {
        List<CategoryEntity> list = this.list();
        if (Objects.isNull(list)) {
            return R.error("无商品分类信息");
        }

        List<CategoryVo> categoryVos = getCategoryVos(list);


        return R.ok().put("data", categoryVos);
    }

    private List<CategoryVo> getCategoryVos(List<CategoryEntity> list) {
        List<CategoryVo> vos = CopyBean.copyBeanList(list, CategoryVo.class);

        Map<Long, CategoryVo> map = new HashMap<>();

        for (CategoryVo categoryEntity : vos) {
            map.put(categoryEntity.getCatId(), categoryEntity);
        }

        List<CategoryVo> categoryVos = new ArrayList<>();
        for (CategoryVo value : map.values()) {
            CategoryVo fatherCategory = map.get(value.getParentCid());

            if (!Objects.isNull(fatherCategory)) {
                //说明有父分类
                if (CollUtil.isEmpty(fatherCategory.getChildren())) {
                    fatherCategory.setChildren(new ArrayList<>());
                }
                fatherCategory.getChildren().add(value);
                categorySonSort(fatherCategory.getChildren());
            } else {
                categoryVos.add(value);
                categorySonSort(categoryVos);
            }
        }
        return categoryVos;
    }

    private void categorySonSort(List<CategoryVo> sonSort) {

        sonSort.sort(new Comparator<CategoryVo>() {
            @Override
            public int compare(CategoryVo o1, CategoryVo o2) {
                return (o1.getSort() == null ? 0 : o1.getSort()) - (o2.getSort() == null ? 0 : o2.getSort());
            }
        });


    }

    @Override
    public void removeMenuByIds(List<Long> longs) {

        categoryDao.deleteByIds(longs);


    }

    @Override
    public Long[] getCatelogIdPath(Long catelogId) {
        List<Long> catelogIdPath = new ArrayList<>();
        getCatIdPath(catelogIdPath, catelogId);

        Collections.reverse(catelogIdPath);

        return catelogIdPath.toArray(new Long[catelogIdPath.size()]);
    }

//    @CacheEvict(value = {"category"},key = "'listLevel1'")
//    @Caching(evict = {
//            @CacheEvict(value = {"category"},key = "'listLevel1'"),
//            @CacheEvict(value = {"category"},key = "'indexCategory'"),
//    })
    @CacheEvict(value = {"category"},allEntries = true)
    @Override
    public void updateByIdAndintermediateTable(CategoryEntity category) {
        this.updateById(category);

        categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
    }


    private void getCatIdPath(List<Long> catelogIdPath, Long catelogId) {
        CategoryEntity category = this.getById(catelogId);
        if (!Objects.isNull(category)) {
            catelogIdPath.add(category.getCatId());
            getCatIdPath(catelogIdPath, category.getParentCid());
        }
//为空代表顶级
    }

    /**
     * @return java.util.Map<java.lang.String, java.util.List < com.zhangzhan.gulimallproduct.vos.Catelog2Vo>>
     * @description 获取分类json
     * @author zhangyiheng
     * @date 2024/6/21 3:02
     */
    @Override
    @Cacheable(value = "category",key = "#root.method.name")
    public Map<String, List<Catelog2Vo>> indexCategory() {
        Map<String, List<Catelog2Vo>> map = indexCategoryForDb();

        return map;

    }

    @Override
    @Cacheable(cacheNames = {"category"},key = "#root.method.name")
    public List<CategoryEntity> listLevel1() {
        log.debug("listLevel1进入查询。。。");
        return list(Wrappers.<CategoryEntity>lambdaQuery().eq(CategoryEntity::getCatLevel,1));
    }


    public Map<String, List<Catelog2Vo>> indexCategoryForDb() {

        List<CategoryEntity> list = list();

        Map<String, List<Catelog2Vo>> map = list.stream().filter(po -> po.getCatLevel() == 1).collect(Collectors.toMap(k -> k.getCatId().toString(), po -> {
            List<Catelog2Vo> catelog2Vos = new ArrayList<>();


            List<CategoryEntity> level2 = getCategoryEntities(list,po.getCatId());
            if (CollUtil.isNotEmpty(level2)) {
                level2.forEach(po2 -> {
                    Catelog2Vo catelog2Vo = new Catelog2Vo();
                    catelog2Vo.setCatalog1Id(po.getCatId().toString());
                    catelog2Vo.setId(po2.getCatId().toString());
                    catelog2Vo.setName(po2.getName());

                    List<CategoryEntity> level3 = getCategoryEntities(list,po2.getCatId());
                    List<Catelog2Vo.Category3Vo> list3;
                    if (CollUtil.isNotEmpty(level3)) {
                        list3 = new ArrayList<>();
                        level3.forEach(po3 -> {
                            Catelog2Vo.Category3Vo category3Vo = new Catelog2Vo.Category3Vo();
                            category3Vo.setCatalog2Id(po2.getCatId().toString());
                            category3Vo.setId(po3.getCatId().toString());
                            category3Vo.setName(po3.getName());
                            list3.add(category3Vo);
                        });
                    } else {
                        list3 = null;
                    }

                    catelog2Vo.setCatalog3List(list3);
                    catelog2Vos.add(catelog2Vo);
                });
            }

            return catelog2Vos;
        }));

        return map;
    }



    private List<CategoryEntity> getCategoryEntities(List<CategoryEntity> list, Long catId) {
        return list.stream().filter(po -> {
            return po.getParentCid().equals(catId);
        }).collect(Collectors.toList());
    }


}